package cn.iocoder.yudao.module.scrm.strategy;

import cn.hutool.core.lang.Pair;
import cn.iocoder.yudao.module.scrm.controller.admin.refund.vo.RefundSaveReqVO;
import cn.iocoder.yudao.module.scrm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.scrm.strategy.strategyimpl.OrderInvoiceStrategyImpl;
import cn.iocoder.yudao.module.scrm.strategy.strategyimpl.OrderReceivableRefundInvoiceStrategyImpl;
import cn.iocoder.yudao.module.scrm.strategy.strategyimpl.OrderReceivableStrategyImpl;
import cn.iocoder.yudao.module.scrm.strategy.strategyimpl.OrderRefundStrategyImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author LiZhiMin
 * 比较策略工厂类，用于管理和检索不同的 {@link CompareStrategy} 实例。
 * <p>
 * 该类作为一个策略注册中心，将不同的比较策略根据业务类型对进行存储和管理。
 * 通过这个工厂类，可以根据业务类型对获取对应的比较策略实例。
 * </p>
 * @Date 2024/9/3 10:50
 */
@Component
public class CompareStrategyFactory {

    /**
     * 存储比较策略的映射表。
     * <p>
     * 这个映射表的键是一个 {@link Pair} 对象，表示主要业务类型和外部业务类型的组合。
     * 值是对应的 {@link CompareStrategy} 实例。
     * </p>
     */
    private final Map<Pair<CrmBizTypeEnum, CrmBizTypeEnum>, CompareStrategy> strategyFactory = new HashMap<>();

    /**
     * 构造函数，初始化工厂并注册策略。
     * <p>
     * 通过传入的策略列表，遍历每一个策略实例，并将其注册到工厂中。
     * 策略的注册是基于其具体实现类型来进行的。
     * </p>
     *
     * @param strategyList 需要注册的 {@link CompareStrategy} 实例列表。
     */
    @Autowired
    public CompareStrategyFactory(List<CompareStrategy> strategyList) {
        for (CompareStrategy strategy : strategyList) {
            // 将处理器注册到工厂中（可以根据需要调整键的类型）
            if (strategy instanceof OrderReceivableStrategyImpl) {
                strategyFactory.put(Pair.of(CrmBizTypeEnum.CRM_RECEIVABLE, CrmBizTypeEnum.CRM_ORDER), strategy);
            } else if (strategy instanceof OrderInvoiceStrategyImpl) {
                strategyFactory.put(Pair.of(CrmBizTypeEnum.CRM_INVOICE, CrmBizTypeEnum.CRM_ORDER), strategy);
            } else if (strategy instanceof OrderRefundStrategyImpl) {
                strategyFactory.put(Pair.of(CrmBizTypeEnum.CRM_REFUND, CrmBizTypeEnum.CRM_ORDER), strategy);
            } else if (strategy instanceof OrderReceivableRefundInvoiceStrategyImpl) {
                strategyFactory.put(Pair.of( CrmBizTypeEnum.CRM_ORDER,CrmBizTypeEnum.CRM_INVOICE ), strategy);
                strategyFactory.put(Pair.of( CrmBizTypeEnum.CRM_ORDER,CrmBizTypeEnum.CRM_RECEIVABLE ), strategy);
                strategyFactory.put(Pair.of( CrmBizTypeEnum.CRM_ORDER,CrmBizTypeEnum.CRM_REFUND ), strategy);
        }
        }
    }

    /**
     * 根据主要业务类型和外部业务类型获取对应的比较策略实例。
     * <p>
     * 根据提供的主要业务类型和外部业务类型从工厂中查找并返回相应的 {@link CompareStrategy} 实例。
     * </p>
     *
     * @param majorKey   主要业务类型。
     * @param foreignKey 外部业务类型。
     * @return 对应的 {@link CompareStrategy} 实例，如果未找到则返回 {@code null}。
     */
    public CompareStrategy getStrategy(CrmBizTypeEnum majorKey, CrmBizTypeEnum foreignKey) {
        return strategyFactory.get(Pair.of(majorKey, foreignKey));
    }
}
